﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace Oxage.CNC.Models
{
	public class XamlPathDataCodeBlock : IMachineCodeBlock
	{
		#region Constructor
		public XamlPathDataCodeBlock()
		{
			this.inlines = new List<IMachineCodeInline>();
		}

		public XamlPathDataCodeBlock(string block)
		{
			this.inlines = new List<IMachineCodeInline>();
			Parse(block);
		}
		#endregion

		#region Public properties
		public int LineNumber
		{
			get;
			set;
		}
		#endregion

		#region Public methods
		public void Parse(string line)
		{
			//Matches a segment
			var matches = Regex.Matches(line, @"(?<segment>(?<code>\w)[\d\-\+\.\s,]+)", RegexOptions.IgnoreCase);
			foreach (Match match in matches)
			{
				IMachineCodeInline inline = null;
				string code = match.Groups["code"].Value;
				string segment = match.Groups["segment"].Value;

				switch (code.ToUpper())
				{
					case "M":
						inline = new MoveInline(segment);
						break;

					case "L":
						inline = new LineInline(segment);
						break;

					case "C":
						inline = new CubicBezierCurveInline(segment);
						break;

					case "A":
						inline = new ArcInline(segment);
						break;

					case "Z":
						inline = new CloseInline(segment);
						break;

					default:
						throw new NotSupportedException();
				}

				this.Inlines.Add(inline);
			}
		}

		public override string ToString()
		{
			if (this.Inlines == null)
			{
				return "";
			}

			var builder = new StringBuilder();
			foreach (var inline in this.Inlines)
			{
				if (builder.Length > 0)
				{
					//White space between inlines
					builder.Append(" ");
				}
				builder.Append(inline.ToString());
			}
			return builder.ToString().Trim();
		}
		#endregion

		#region IMachineCodeBlock Members
		private List<IMachineCodeInline> inlines;

		public List<IMachineCodeInline> Inlines
		{
			get
			{
				return this.inlines;
			}
		}

		public void Add(IMachineCodeInline inline)
		{
			this.Inlines.Add(inline);
		}
		#endregion

		#region IEnumerable<IMachineCodeInline> Members
		public IEnumerator<IMachineCodeInline> GetEnumerator()
		{
			return this.inlines.GetEnumerator();
		}
		#endregion

		#region IEnumerable Members
		IEnumerator IEnumerable.GetEnumerator()
		{
			return this.inlines.GetEnumerator();
		}
		#endregion
	}
}
